/*
 * @Author: yangzonglong
 * @Date: 2021-05-25 14:43:54
 * @version: v1.0.0
 * @Descripttion: table
 * @LastEditors: yangzonglong
 * @LastEditTime: 2023-08-28 22:58:34
 * @Auditor:
 */
import moment from 'moment';
import React, { useState, useEffect, useMemo, useRef } from 'react';
import JsBarcode from 'jsbarcode';
import classnames from 'classnames';
import styles from './table.module.scss';
import { textReplaceStr } from '../../../util';
import { moneyFormat } from '@library/components/table/util';

const QRCode = require('qrcode.react');
const _Column = require('./Column');
const baseTitleStyle = { textAlign: 'left' };
const bigTitleStyle = { ...baseTitleStyle, fontSize: '16px', fontWeight: 600 };

const Column = _Column['default'];
const tbStyle = { background: '#fff', width: '100%' };
const T = window.$app.t;

const ControlMap = {
  thead: (props) => <thead {...props} style={{ display: 'table-header-group' }} />,
  div: (props) => <thead {...props} style={{ display: 'table-header-group' }} />
};

const Table = (props) => {
  let children = props.children || [];
  const allWidth = children.reduce((all, now) => all + (+(now.props.width || 0)), 0);
  const printBorder = props.printBorder;
  const tableOptions = {};

  const HeadDiv = printBorder ? ControlMap.thead : ControlMap.div;

  const handleThTdStyle = (width) => {
    if (!width) return {};
    return { width: ((width / allWidth * 100).toFixed(3) + '%') };
  };

  if (printBorder) {
    tableOptions.width = '100%';
    tableOptions.border = '1';
  }

  return (
    <div className={styles.mbTable} id="mbTable">
      <table {...tableOptions} className={classnames({
        [styles.printBorderTable]: printBorder,
        [styles.table]: !printBorder
      })}>
        <HeadDiv className={
          classnames({
            [styles.anttablethead]: !printBorder
          })
        }>
          <tr>
            {children.map((ele) => (
              <th key={ele.key} style={handleThTdStyle(ele?.props?.width)}>
                {ele?.props?.title}
              </th>
            ))}
          </tr>
        </HeadDiv>
        <tbody>

          {props?.dataSource?.map((data, index) => {
            return (
              <tr key={data.id} style={props.dataSource[0]._trStyle}>
                {children.map((ele) => (
                  <td key={ele.key} style={handleThTdStyle(ele?.props?.width)}>
                    {ele?.props?.render?.(data, data, index)}
                  </td>
                ))}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
};

const BarCode = (props) => {
  useEffect(() => {
    if (!props.value) return;
    JsBarcode(refs.current, props.value, {
      displayValue: false,
      width: 1.8,
      height: 50,
      margin: 0,
    });
  }, [props.value]);

  const refs = useRef(null);

  return <svg ref={refs} />;
};

export default (props, ref) => {
  const { tableProps, title, titleEn, initialValue, } = props;
  const [dataSource, setDataSource] = useState([]);

  useEffect(() => {
    if (initialValue) setDataSource(initialValue);
    else if (tableProps.initialValue) {
      let _v = tableProps.initialValue;
      Array.isArray(_v) && setDataSource(_v?.map((item, index) => ({ ...item, id: item.id || `$_${index}` })));
    }
  }, [initialValue, tableProps.initialValue]);

  const render = (text, record, column) => {
    const options = column.options;

    let value = record[column.dataIndex];
    let textAlign = column?.textAlign || 'left';
    if (column.type === 'radio' || column.type === 'select') {
      let _item = options?.dataSource?.filter((item) => item.value === value);
      value = _item?.[0]?.['label'];
    } else if (column.type === 'checkbox') {
      let _item = options?.dataSource?.filter((item) => value?.includes(item.value));
      value = _item.reduce((all, now) => all + now.label + ' ', '');
    } else if (column.type === 'datePicker') {
      value = value ? moment(value).format(options.format) : '';
    } else if (column.type === 'statusTransfer') {
      const statusTransfer = JSON.parse(localStorage.i18nextLng === 'en' ? column.statusTransferEn || column.statusTransfer : column.statusTransfer || '{}');
      value = statusTransfer?.[value] || value;
    } else if (column.type === 'text') {
      value = value !== undefined && value !== null ? value : options?.text;
    } else if (column.type === "inputNum") {
      if (options?.formatterMoney) {
        value = moneyFormat(value);
      } else if (options?.precision) {
        value = Number(value).toFixed(options.precision);
      }
    } else if (column.type === 'code') {
      return column.printType && value ? column.printType === "barCode" ?
        <BarCode value={value} /> :
        <QRCode value={value} size={60} /> : '';
    } else {
      const showFieldName = options?.showFieldName;
      if (showFieldName) value = value?.[showFieldName] || value;
    }

    if (typeof value === 'boolean') {
      return <div style={{
        textAlign, width: '100%', wordBreak: 'break-all',
        wordWrap: 'break-word'
      }}>{T(value + '')}</div>;
    }

    // eslint-disable-next-line eqeqeq
    return <div style={{
      textAlign, width: '100%', wordBreak: 'break-all',
      wordWrap: 'break-word',
      whiteSpace: 'pre-wrap',
      ...record._textStyle
    }}>{value || value == 0 ? value : ''}</div>;
  };

  const columns = useMemo(() => {
    if (!tableProps) return [];
    let _columns = tableProps.columns?.filter(item => item.print !== false && item.hideInput !== true);
    if (tableProps.showItemNo) {
      const itemColumn = [
        {
          dataIndex: 'itemNo',
          width: tableProps.itemNoWidth || 130,
          title: '行号',
          render: (text, record, index) => <span>{record?.itemNo || (index + 1) * 10}</span>,
        },
      ];

      return itemColumn.concat(_columns);
    }

    return _columns;
  }, [tableProps]);

  return (
    <div style={tbStyle} className='printview-table'>
      {
        Array.isArray(dataSource?.[0]) ? dataSource.map(ele => {
          return <>
            <div style={tableProps.showBigTitle ? bigTitleStyle : baseTitleStyle}>{textReplaceStr(localStorage.i18nextLng === 'en' ? titleEn : title, ele?.[0] || {})}</div>
            <Table printBorder={props.printBorder} dataSource={ele}  >
              {columns.map((item) => (
                <Column
                  key={item.dataIndex}
                  width={item.width * 2}
                  title={localStorage.i18nextLng === 'en' ? item?.titleEn : item.title}
                  render={(text, record, index) => {
                    if (item.render) return item.render(text, record, index);
                    return render(text, record, item);
                  }}
                />
              ))}
            </Table>
          </>;
        }) :
          <>
            <div style={tableProps.showBigTitle ? bigTitleStyle : baseTitleStyle}>{textReplaceStr(localStorage.i18nextLng === 'en' ? titleEn : title, dataSource?.[0] || {})}</div>
            <Table printBorder={props.printBorder} dataSource={dataSource}  >
              {columns.map((item) => (
                <Column
                  key={item.dataIndex}
                  width={item.width * 2}
                  title={
                    <pre style={{
                      margin: 0,
                      whiteSpace: 'pre-wrap',
                      wordWrap: 'break-word',
                      width: '100%',
                      textAlign: item.textAlign || 'left'
                    }}>
                      {localStorage.i18nextLng === 'en' ? item?.titleEn : item.title}
                    </pre>
                  }
                  render={(text, record, index) => {
                    if (item.render) return item.render(text, record, index);
                    return render(text, record, item);
                  }}
                />
              ))}
            </Table>

          </>
      }

    </div>
  );
};
